package com.hang.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hang.entity.*;
import com.hang.exception.MyException;
import com.hang.exception.MyExceptionEnum;
import com.hang.mapper.*;
import com.hang.mapstruct.ModuleMapStruct;
import com.hang.model.dto.base.ConditionDTO;
import com.hang.model.dto.request.ModuleModelDTO;
import com.hang.model.dto.request.ModuleQueryDTO;
import com.hang.model.dto.response.ModuleQueryListVO;
import com.hang.model.vo.ModuleDetailVO;
import com.hang.model.vo.ModuleInfoVO;
import com.hang.service.*;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 *
 */
@Service
@AllArgsConstructor
public class ModuleServiceImpl extends ServiceImpl<ModuleMapper, Module>
    implements IModuleService{

    private ModuleMapStruct moduleMapStruct;

    private TbDocumentMapper documentMapper;

    private TbFileMapper fileMapper;

    private BugMapper bugMapper;

    private TaskMapper taskMapper;

    /**
     * 新增项目模块
     * @param moduleModelDTO
     */
    @Override
    public void createItemModule(ModuleModelDTO moduleModelDTO) {
        Module module = moduleMapStruct.ModuleModelDTOToModule(moduleModelDTO);
        this.baseMapper.insert(module);
    }

    /**
     * 更新项目模块
     * @param moduleModelDTO
     */
    @Override
    public void editItemModule(ModuleModelDTO moduleModelDTO) {
        Long moduleId = moduleModelDTO.getModuleId();

        if(ObjectUtil.isEmpty(moduleId)){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        Module dbModule = Optional.ofNullable(this.baseMapper.selectById(moduleId)).orElse(null);
        if(ObjectUtil.isEmpty(dbModule)){
            throw new MyException(MyExceptionEnum.DATA_DOES_NOT_EXIST);
        }

        //更新操作
        BeanUtils.copyProperties(moduleModelDTO,dbModule);

        this.baseMapper.updateById(dbModule);
    }

    /**
     * 删除项目模块
     * @param moduleId
     */
    @Override
    public void deleteModule(Long moduleId) {
        if(ObjectUtil.isEmpty(moduleId)){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        //判断该ID下是否有文档、文件、故障、任务，如果有，则不允许删除
        QueryWrapper<TbDocument> documentQueryWrapper = new QueryWrapper<>();
        documentQueryWrapper.lambda().eq(TbDocument::getModuleId,moduleId);

        Integer documentCounts = Optional.of(documentMapper.selectCount(documentQueryWrapper)).orElse(0);
        if(documentCounts > 0){
            throw new MyException(MyExceptionEnum.DOCUMENT_EXISTS);
        }

        QueryWrapper<TbFile> fileQueryWrapper = new QueryWrapper<>();
        fileQueryWrapper.lambda().eq(TbFile::getModuleId,moduleId);

        Integer fileCounts = Optional.of(fileMapper.selectCount(fileQueryWrapper)).orElse(0);
        if(fileCounts > 0){
            throw new MyException(MyExceptionEnum.FILE_EXISTS);
        }

        QueryWrapper<Bug> bugQueryWrapper = new QueryWrapper<>();
        bugQueryWrapper.lambda().eq(Bug::getModuleId,moduleId);

        Integer bugCounts = Optional.of(bugMapper.selectCount(bugQueryWrapper)).orElse(0);
        if(bugCounts > 0){
            throw new MyException(MyExceptionEnum.BUG_EXISTS);
        }

        QueryWrapper<Task> taskQueryWrapper = new QueryWrapper<>();
        taskQueryWrapper.lambda().eq(Task::getModuleId,moduleId);

        Integer taskCounts = Optional.of(taskMapper.selectCount(taskQueryWrapper)).orElse(0);
        if(taskCounts > 0){
            throw new MyException(MyExceptionEnum.TASK_EXISTS);
        }

        //若都符合，那么就可以删除这个模块
        this.removeById(moduleId);
    }

    /**
     * 批量删除
     * @param moduleIdList
     */
    @Override
    public void deleteModuleList(List<Long> moduleIdList) {
        if(ObjectUtil.isNull(moduleIdList) || moduleIdList.size() < 1){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        //判断: in(集合是否满足删除要素)
        QueryWrapper<TbDocument> documentQueryWrapper = new QueryWrapper<>();
        documentQueryWrapper.lambda().in(TbDocument::getModuleId,moduleIdList);
        Integer documentCounts = Optional.of(documentMapper.selectCount(documentQueryWrapper)).orElse(0);
        if(documentCounts > 0){
            throw new MyException(MyExceptionEnum.DOCUMENT_EXISTS);
        }

        QueryWrapper<TbFile> fileQueryWrapper = new QueryWrapper<>();
        fileQueryWrapper.lambda().in(TbFile::getModuleId,moduleIdList);
        Integer fileCounts = Optional.of(fileMapper.selectCount(fileQueryWrapper)).orElse(0);
        if(fileCounts > 0){
            throw new MyException(MyExceptionEnum.FILE_EXISTS);
        }

        QueryWrapper<Bug> bugQueryWrapper = new QueryWrapper<>();
        bugQueryWrapper.lambda().in(Bug::getModuleId,moduleIdList);
        Integer bugCounts = Optional.of(bugMapper.selectCount(bugQueryWrapper)).orElse(0);
        if(bugCounts > 0){
            throw new MyException(MyExceptionEnum.BUG_EXISTS);
        }

        QueryWrapper<Task> taskQueryWrapper = new QueryWrapper<>();
        taskQueryWrapper.lambda().in(Task::getModuleId,moduleIdList);
        Integer taskCounts = Optional.of(taskMapper.selectCount(taskQueryWrapper)).orElse(0);
        if(taskCounts > 0){
            throw new MyException(MyExceptionEnum.TASK_EXISTS);
        }

        //若都符合，则允许删除
        this.removeByIds(moduleIdList);
    }

    /**
     * 条件查询模块列表
     * @param moduleQueryDTO
     * @return
     */
    @Override
    public ModuleQueryListVO getModuleListByCondition(ModuleQueryDTO moduleQueryDTO) {
        ModuleQueryListVO moduleQueryListVO = new ModuleQueryListVO();

        Long itemId = moduleQueryDTO.getItemId();

        String condition = Optional.ofNullable(moduleQueryDTO.getCondition()).orElse("");
        Integer moduleType = Optional.ofNullable(moduleQueryDTO.getModuleType()).orElse(0);
        Integer pageNum = moduleQueryDTO.getPageNum();
        Integer pageSize = moduleQueryDTO.getPageSize();

        QueryWrapper<Module> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.lambda().eq(Module::getItemId,itemId);

        if(StrUtil.isNotBlank(condition)){
            moduleQueryWrapper
                    .lambda()
                    .like(Module::getModuleName,condition)
                    .or()
                    .like(Module::getCreateBy,condition)
                    .or()
                    .like(Module::getModuleUrl,condition);
        }

        if(moduleType!=0){
            moduleQueryWrapper.lambda().eq(Module::getModuleType,moduleType);
        }

        //搜索出符合条件的数据
        Page<Module> page = new Page<>(pageNum,pageSize);
        List<Module> moduleList = Optional.ofNullable(this.baseMapper.selectPage(page,moduleQueryWrapper).getRecords()).orElse(new LinkedList<>());

        List<ModuleInfoVO> moduleInfoVOList = moduleMapStruct.moduleListToModuleInfoVOList(moduleList);

        moduleQueryListVO.setTotal(this.baseMapper.selectCount(moduleQueryWrapper));
        moduleQueryListVO.setModuleInfoVOList(moduleInfoVOList);

        return moduleQueryListVO;
    }

    /**
     * 获取模块详情信息
     * @param moduleId
     * @return
     */
    @Override
    public ModuleDetailVO getModuleDetailById(Long moduleId) {
        if(ObjectUtil.isNull(moduleId)){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        Module dbModule = Optional.ofNullable(this.getById(moduleId)).orElse(null);

        if(ObjectUtil.isEmpty(dbModule)){
            throw new MyException(MyExceptionEnum.DATA_DOES_NOT_EXIST);
        }

        //拷贝基本数据
        ModuleDetailVO moduleDetailVO = moduleMapStruct.moduleToModuleDetailVO(dbModule);

        //统计数据的补充

        //故障数据
        QueryWrapper<Bug> bugQueryWrapper = new QueryWrapper<>();
        bugQueryWrapper.lambda().eq(Bug::getModuleId,moduleId);
        moduleDetailVO.setModuleBugCount(Optional.ofNullable(bugMapper.selectCount(bugQueryWrapper)).orElse(0));

        //任务数据
        QueryWrapper<Task> taskQueryWrapper = new QueryWrapper<>();
        taskQueryWrapper.lambda().eq(Task::getModuleId,moduleId);
        moduleDetailVO.setModuleTaskCount(Optional.ofNullable(taskMapper.selectCount(taskQueryWrapper)).orElse(0));

        //文档数据
        QueryWrapper<TbDocument> documentQueryWrapper = new QueryWrapper<>();
        documentQueryWrapper.lambda().eq(TbDocument::getModuleId,moduleId);
        moduleDetailVO.setModuleDocumentCount(Optional.ofNullable(documentMapper.selectCount(documentQueryWrapper)).orElse(0));

        //文件数据
        QueryWrapper<TbFile> fileQueryWrapper = new QueryWrapper<>();
        fileQueryWrapper.lambda().eq(TbFile::getModuleId,moduleId);
        moduleDetailVO.setModuleFileCount(Optional.ofNullable(fileMapper.selectCount(fileQueryWrapper)).orElse(0));

        return moduleDetailVO;
    }
}




